/******************************************************************************
  Filename:    JackpotPinatasGuts.h
  Developer:   Ryan Sauls
  Create date: 8/09/2007
*******************************************************************************
  Description: This is the class declaration for the slot gut of the
               Australian Slot machine called Jackpot Pinatas
*******************************************************************************
        Copyright (c) 2007 - Realtime Gaming.  All rights reserved.
*******************************************************************************/

#pragma once
#include "slotguts.h"

class JackpotPinatasGuts :
    public SlotGuts
{
private:
    typedef SlotGuts baseclass;

    //Include common class constants
    #include "JackpotPinatasCommon.h"

    //Guts ID Range
    enum ValidGutsIds
    {
        VALID_GUTS_START = 4100,
        VALID_GUTS_END = VALID_GUTS_START + 99
    };

    // Probability Tables
    enum ProbabilityTables
    {
        PROB_TABLE_NUMBER_OF_ROUNDS,
        PROB_TABLE_PINATA_PRIZES,
        PROB_TABLE_BONUS_ROUND_FREE_GAMES
    };
    
	// Helpful lookup arrays.
	static SpinResult s_aLineWinSpinResults[][6];
	static SpinResult s_aScatterSpinResults[6];	
    
    // Inline functions to use with the arrays that also do
	// bounds checking.
	static SpinResult lookupLineWinSpinResult( uint8 nIconType, uint8 nCount )
	{
		if ( nIconType < NUM_VALID_ICONS && nCount < 6 )
		{
			return s_aLineWinSpinResults[ nIconType ][ nCount ];
		}

		ASSERT( false );
		return EVT_INVALID;
	}

	static SpinResult lookupScatterSpinResult( uint8 nCount )
	{
		if ( nCount < 6 )
		{
			return s_aScatterSpinResults[ nCount ];
		}

		ASSERT( false );
		return EVT_INVALID;
	}

    static bool8 canBeSubstituted( uint8 iconID )
    {
        return iconID != ICON_BULL_PINATA &&
               iconID != ICON_DOG_PINATA &&
               iconID != ICON_DONKEY_PINATA;
    }

    static bool8 isBullPinataWin( uint8 sr )
    {
        return sr == EVT_TWO_BULL_PINATA ||
            sr == EVT_THREE_BULL_PINATA ||
            sr == EVT_FOUR_BULL_PINATA ||
            sr == EVT_FIVE_BULL_PINATA;
    }
    
	bool isSubstituteIconLineWinGreater( SpinResult srSubIconLineWin, SpinResult srTestResult ) const;

public:
    JackpotPinatasGuts(void);
    virtual ~JackpotPinatasGuts(void);

    
    virtual bool8 isValidGuts();

protected:    
	virtual void classifyStops( SpinLine* spinline, uint8* stops, uint8 bet, uint8 line,
		uint8& rtnresult, uint8& multiplier );

    virtual void preSpinClassifyResults( SlotSpin* spin );

    virtual void postSpinClassifyResults( SlotSpin* spin );

	virtual void classifyScatters( SlotSpin *spin );

    virtual void getGameModeMultiplierAndNoteId( uint8& nGameModeMultiplier, uint8& nNoteId );

	virtual bool8 processClientData( uint8 bonusGameType, int32 bonusDataCount, int32 *bonusData );

    virtual bool8 hasSavedGames();

    virtual bool8 getProgressiveContribution(int32 nBetPerLine, int32 nLineCount, int32& nContribution, int32& nContributionFractionalCents);

    virtual void Debug_SetLoserStops( uint8 *pStops );

private:    
    bool8       isDonkeyIcon( uint8* pStops, int32 reel ) const;

	SpinResult  getDonkeyPinataWinResult( uint8* stops ) const;

	SpinResult  getLineWinResultWithPossibleSubstitution(
        uint8* stops, uint8 line, uint8 testIcon, bool& bSubstitution );

    SpinResult  getScatterResults( SlotSpin* spin, int32& nNumberScatterIcons, int32& nScatterPositions ) const;

    void        addFeatureTriggerScatter( SlotSpin* spin, int32 nNumScatterIcons, int32 nScatterPositions );

    // Feature game management
    enum
    {
        DECREMENT = -1,
        INCREMENT = 1
    };

    void        resetJackpotSpinLine();
    void        setJackpotSpinLine(int32 index);
    int32       getJackpotSpinLine() const;

    void        beginNewFeature();

    void        resetPicksThisRound();
    void        decrementPicksThisRound();

    int32       getPinatasPicksRemaining() const;
    int32       adjustPinataPicksRemaining(int32 changeAmount);

    int32       getBonusRoundsRemaining() const;
    int32       adjustBonusRoundsRemaining(int32 changeAmount);

    void        initializeCurrentRound();
    void        incrementCurrentRound();

    
    int32       getThisRoundBonusRoundFlag() const;
    void        setThisRoundBonusRoundFlag();
    void        resetThisRoundBonusRoundFlag();

    bool8       pinataHasRose() const;

    int32       getPinataPickPrize();

    bool        flipACoin() const;
    void        awardFreeGames();

    
    bool8       isPinataSelected(int32 nPinata) const;
    void        updatePinataSelectedMask( int32 nPinata );
    void        setPinataSelectedMask( int32 nMask );
    int32       getPinataSelectedMask() const;

    
    int32       getBonusGameResultIndex() const;
    int32       postIncrementBonusGameResultIndex();

    // Debug help
	enum
	{
        // Controls how many rounds in the feature are won.
    	EVT_DEBUG_BONUS_ROUND_0X = BEGIN_SUB_MODIFY_NEXT_RESULT_FUNCTION_RANGE,
		EVT_DEBUG_BONUS_ROUND_1X,
		EVT_DEBUG_BONUS_ROUND_2X,
		EVT_DEBUG_BONUS_ROUND_3X,
		EVT_DEBUG_BONUS_ROUND_4X,
		EVT_DEBUG_BONUS_ROUND_5X,

        // Controls the prize associated with each pinata.
		EVT_DEBUG_BONUS_PRIZE_2X,
		EVT_DEBUG_BONUS_PRIZE_3X,
		EVT_DEBUG_BONUS_PRIZE_5X,
		EVT_DEBUG_BONUS_PRIZE_10X,
		EVT_DEBUG_BONUS_PRIZE_25X,
		EVT_DEBUG_BONUS_PRIZE_200X,

        // Controls the number of free games won
        EVT_DEBUG_BONUS_FREE_GAMES_5,
        EVT_DEBUG_BONUS_FREE_GAMES_10,
        EVT_DEBUG_BONUS_FREE_GAMES_15,
        EVT_DEBUG_BONUS_FREE_GAMES_25,
	};

    virtual void initDebugFunctionMap();

    void Debug_SetBonusRounds( int32 numBonusRounds, SlotSpin* );
    void Debug_SetNextBonusPrize( int32 nextPrizeAmount, SlotSpin* );
    void Debug_SetFeatureFreeGamesPrize( int32 numFreeGames, SlotSpin* );

    std::vector<int32> m_BonusRoundsToWin;
    std::vector<int32> m_BonusPrizesToWin;
    std::vector<int32> m_FreeGamesToWin;

    int32 m_nBonusRoundsIndex ;
    int32 m_nBonusPrizesIndex ;
    int32 m_nFreeGamesIndex ;

    int32 getRandomValue( int32& index, std::vector<int32>& vec, int32 defaultProbTable ) const;
};
